<?php
/**
 * Created by PhpStorm.
 * Use: ulue r=builder/help --
 * Date: 14-5-12
 * Time: 下午10:33
 */
namespace ulue\cli;

use Ioc;
use Ulue;
use ulue\core\controller\AbstractController;
use ulue\cli\router\Router;
use ulue\cli\io\IO;

class Controller extends AbstractController
{
    public $defaultCommand = 'index';

    //将要执行的方法名
    private $actionName  = '';

    // 方法名后缀
    protected $actionSuffix  = 'Command';

    /**
     * @var IO
     */
    protected $io;

    /**
     * @param $actionName
     */
    public function prepareExecute( &$actionName)
    {
        /**
         * 在 $this->init() 中使用$this->setActionName($value)
         * 设置 $this->actionName 的话，将会覆盖 原本将要执行的 $actionName
         */
        if ($this->actionName && is_string($this->actionName)) {
            $actionName       = $this->actionName;
        } else {
            $this->actionName = $actionName;
        }

        $this->beforeExecute();
    }

    public function execute()
    {
        $actionName = Ioc::get('app.router')->get('action');

        $this->prepareExecute($actionName);

        $theActionMethod = $actionName.ucfirst( $this->actionSuffix );

        /**
         * @see \ulue\core\router\Router::$params
         * @var $params array 请求参数部分
         */
        $params = $this->getIo()->getOptions();

        # 1). 控制器存在 $actionName 方法 ，@example public function index()
        if ( method_exists( $this, $theActionMethod ) ) {

            // 执行请求的方法
            if( $params = $this->getMethodParameters($this, $theActionMethod, $params) ) {
                call_user_func_array( [$this, $theActionMethod], (array) $params);
            } else {
                $this->$theActionMethod();
            }

        # 2). 开启调试
        } else if (Ulue::$app->debug) {
            throw new \DRuntimeException(get_class($this)."->{$theActionMethod}() 方法不存在！");

        # 3). 跳至 错误页面
        } else {
            $this->_theErrorCommand();
        }

        $this->afterExecute($output);

        //return ($this->output = $output);
    }

    public function _theErrorCommand()
    {
        exit("\n\n !!! access error !!!\n\n");
    }

    /**
     * setRouteAction 判断请求的控制器方法名
     * @param Router $router
     * @throws \DRuntimeException
     * @return $this
     */
    public function setRouteAction(Router $router)
    {
        $routeActionName  = $router->get('action');

        # 没有输入要访问的控制器，获取默认值
        if (!$routeActionName) {

            $routeActionName = Ulue::$app->get('default.action');

            if ( !$routeActionName ) {
                $routeActionName = $this->defaultCommand;
            }

            # error
            if (!$routeActionName) {
                throw new \DRuntimeException("没有输入要访问的控制器方法，请输入或者设置默认的访问方法!");
            }

            # 将默认值写入请求信息
            $router->set('action', $routeActionName);
        }

        $this->actionName = $routeActionName;

        // defined('ACTION') || define('ACTION'    , $routeActionName );

        return $this;
    }

    /**
     * Set the well execute's action method name;
     * @param $value
     */
    public function setActionName($value)
    {
        $this->actionName=$value;
    }

    /**
     * @return string
     */
    public function getActionName()
    {
        return $this->actionName;
    }

    /**
     * @return IO
     */
    public function getIo()
    {
        if ( !$this->io ) {
            $this->io = Ioc::getShared('app.io');
        }

        return $this->io;
    }

    /**
     * @param IO $io
     */
    public function setIo($io)
    {
        $this->io = $io;
    }
}